#!/usr/bin/env python
# -*- coding:utf8 -*-
"""
Author : mafei
@Date   : 2019/12/01

"""
import time
import uuid

from peewee import CharField, IntegerField,BigIntegerField, PrimaryKeyField, Model, ForeignKeyField, TextField, \
    OperationalError, __exception_wrapper__, \
    TimestampField, FloatField, BooleanField
from playhouse.pool import PooledMySQLDatabase
from playhouse.shortcuts import model_to_dict
from mmonitor.common.config import mysql_db, mysql_password, mysql_server, mysql_user


class RetryOperationalError(object):

    def execute_sql(self, sql, params=None, commit=True):
        try:
            cursor = super(RetryOperationalError, self).execute_sql(
                sql, params, commit)
        except OperationalError:
            if not self.is_closed():
                self.close()
            with __exception_wrapper__:
                cursor = self.cursor()
                cursor.execute(sql, params or ())
                if commit and not self.in_transaction():
                    self.commit()
        return cursor


class MediumTextField(TextField):
    field_type = "MEDIUMTEXT"


class PooledMySQLDatabase(RetryOperationalError, PooledMySQLDatabase):
    pass


db = PooledMySQLDatabase(mysql_db,
                         host=mysql_server,
                         max_connections=50,
                         stale_timeout=300,  # 5 mins
                         user=mysql_user,
                         passwd=mysql_password,
                         charset='utf8')


class BaseModel(Model):
    id = PrimaryKeyField()

    class Meta:
        database = db

    def to_dict(self, **kwargs):
        ml = dict()
        try:
            ml = model_to_dict(self, **kwargs)
        except:
            import traceback
            traceback.print_exc()
        return ml


class UserModel(BaseModel):
    user_id = CharField(default=uuid.uuid4)
    name = CharField()
    password = CharField()
    email = CharField()
    phone = BigIntegerField(null=True)
    is_active = BooleanField(default=False)
    ts = TimestampField(resolution=1000)

    class Meta:
        db_table = "user"


# 用户联系人表
class ContactModel(BaseModel):
    user_id = ForeignKeyField(UserModel)
    email = CharField()
    phone = BigIntegerField(null=True)
    is_active = BooleanField(default=False)
    ts = TimestampField(resolution=1000)

    class Meta:
        db_table = "user_contact"


class WebSiteModel(BaseModel):
    user_id = ForeignKeyField(UserModel)
    name = CharField()  # 监控项的名字
    url = CharField()
    url_id = CharField(default=uuid.uuid4, unique=True)
    interval = IntegerField(default=10)
    ts = TimestampField(resolution=1000)
    job_id = CharField()
    is_enable = IntegerField(default=0)

    class Meta:
        db_table = "web_site"


# 网站告警条件设置
class AlertConfigModel(BaseModel):
    url_id = ForeignKeyField(WebSiteModel)
    keep_ts = BigIntegerField(default=5*60)  # 告警持续时间
    alert_type = IntegerField()   # 预警类型，可以选手机、微信公众号、邮件
    alert_contact = ForeignKeyField(ContactModel)
    alert_interval = IntegerField(default=60*60)  # 告警间隔

    class Meta:
        db_table = "alert_config"


class HistoryModel(BaseModel):
    item_id = ForeignKeyField(WebSiteModel)
    ts = BigIntegerField()
    status_code = IntegerField()
    duration = FloatField()

    class Meta:
        db_table = "web_history"


class ErrorHistoryModel(BaseModel):
    item_id = ForeignKeyField(WebSiteModel)
    error = IntegerField()
    start_time = BigIntegerField()
    update_time = BigIntegerField()

    class Meta:
        db_table = "error_history"


class AlertStatusModel(BaseModel):
    item_id = ForeignKeyField(WebSiteModel)
    error = IntegerField()
    ts = TimestampField(resolution=1000)
    last_notify = BigIntegerField(default=0)

    class Meta:
        db_table = "web_alert_status"


def recheck_table():
    db.connect()

    for subclass in BaseModel.__subclasses__():
        subclass.create_table(fail_silently=True)
    db.close()


if __name__ == "__main__":
    recheck_table()
    '''
           {'item_id': 15, 'start_time': 1577894556943, 'update_time': 1577894556943, 'error': 1}
           '''
    # error_data = {'item_id': 15, 'error': 1}
    # AlertStatusModel.create(**error_data)
    # res = UserModel.create(**{"username":"aa", "password":1, "email": "a@a.com", 'phone':"11111"})
    # print(res.id)
    # res = UserModel.create(**{"username":"ccc", "password":1, "email": "a@a.com", 'phone':"11111"})
    # print(res.id)
    # res = WebSiteModel.create(**{"user_id":res.id, "url":"www.baidu.com", "interval":4})
    # print(res.id)
    #
    # data = {'item_id': 1, 'status_code': 0, 'duration': 0, 'ts': 1576409647697}
    # HistoryModel.create(**data)
    # error_data = {
    #     "item_id": 3,
    #     "error": 1,
    #     "start_time": int(time.time() * 1000),
    #     "update_time": int(time.time() * 1000)
    # }
    # '''
    # {'item_id': 15, 'start_time': 1577894556943, 'update_time': 1577894556943, 'error': 1}
    # '''
    #
    # res = ErrorHistoryModel.create(**error_data)
    # print(res)